package com.smart.community.region.service;

import java.util.Arrays;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Service;

import com.smart.community.region.entity.Region;
import com.smart.community.region.mapper.RegionMapper;

import lombok.extern.slf4j.Slf4j;

/**
 * 区域缓存预热服务
 * 
 * 功能说明：
 * 1. 系统启动时预热区域缓存，提高系统性能
 * 2. 预热常用的区域数据，减少数据库查询
 * 3. 严格按照《Java后端SpringBoot代码开发规范.md》实现
 * 4. 遵循《智慧社区微服务架构总览.md》的缓存设计规范
 * 
 * @author Wu.Liang
 * @since 2025-01-30
 */
@Slf4j
@Service
public class RegionCacheWarmUpService implements CommandLineRunner {

    @Autowired
    private RegionCacheService regionCacheService;

    @Autowired
    private RegionMapper regionMapper;

    @Override
    public void run(String... args) {
        log.info("🔥 开始预热区域缓存...");
        long startTime = System.currentTimeMillis();
        
        try {
            // 预热区域详情缓存
            warmUpRegionDetailCache();
            
            // 预热区域类型缓存
            warmUpRegionTypeCache();
            
            // 预热区域树缓存
            warmUpRegionTreeCache();
            
            // 预热启用区域列表缓存
            warmUpEnabledRegionsCache();
            
            long endTime = System.currentTimeMillis();
            log.info("✅ 区域缓存预热完成! 耗时: {}ms", endTime - startTime);
            
        } catch (Exception e) {
            log.error("❌ 区域缓存预热失败", e);
        }
    }

    /**
     * 预热区域详情缓存
     */
    private void warmUpRegionDetailCache() {
        log.info("预热区域详情缓存...");
        
        try {
            // 获取所有区域ID
            List<Region> allRegions = regionMapper.selectList(null);
            if (allRegions != null && !allRegions.isEmpty()) {
                List<Long> regionIds = allRegions.stream()
                    .map(Region::getId)
                    .collect(java.util.stream.Collectors.toList());
                
                // 预热区域详情缓存
                regionCacheService.warmUpRegionCache(regionIds);
                log.info("预热区域详情缓存完成，区域数量：{}", regionIds.size());
            }
        } catch (Exception e) {
            log.warn("预热区域详情缓存失败", e);
        }
    }

    /**
     * 预热区域类型缓存
     */
    private void warmUpRegionTypeCache() {
        log.info("预热区域类型缓存...");
        
        try {
            // 预热常用的区域类型（1-省，2-市，3-区县，4-街道，5-社区）
            List<Integer> regionTypes = Arrays.asList(1, 2, 3, 4, 5);
            
            // 预热区域类型缓存
            regionCacheService.warmUpRegionTypeCache(regionTypes);
            log.info("预热区域类型缓存完成，区域类型数量：{}", regionTypes.size());
        } catch (Exception e) {
            log.warn("预热区域类型缓存失败", e);
        }
    }

    /**
     * 预热区域树缓存
     */
    private void warmUpRegionTreeCache() {
        log.info("预热区域树缓存...");
        
        try {
            // 预热顶级区域树（parentId为null或0）
            regionCacheService.getRegionTree(null);
            regionCacheService.getRegionTree(0L);
            
            // 预热一些常用的父区域树
            List<Region> parentRegions = regionMapper.selectList(null);
            if (parentRegions != null && !parentRegions.isEmpty()) {
                // 选择前10个父区域进行预热
                List<Long> parentIds = parentRegions.stream()
                    .limit(10)
                    .map(Region::getId)
                    .collect(java.util.stream.Collectors.toList());
                
                for (Long parentId : parentIds) {
                    try {
                        regionCacheService.getRegionTree(parentId);
                    } catch (Exception e) {
                        log.warn("预热区域树缓存失败，父区域ID：{}", parentId, e);
                    }
                }
                
                log.info("预热区域树缓存完成，父区域数量：{}", parentIds.size());
            }
        } catch (Exception e) {
            log.warn("预热区域树缓存失败", e);
        }
    }

    /**
     * 预热启用区域列表缓存
     */
    private void warmUpEnabledRegionsCache() {
        log.info("预热启用区域列表缓存...");
        
        try {
            // 预热启用区域列表
            regionCacheService.getEnabledRegions();
            log.info("预热启用区域列表缓存完成");
        } catch (Exception e) {
            log.warn("预热启用区域列表缓存失败", e);
        }
    }
}
